/*
 * Copyright 2010 Alessandro Bellucci
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.soupframework.gwt.designerpanel.client.designer;

import org.soupframework.gwt.designerpanel.client.DesignerPanel;
import org.soupframework.gwt.designerpanel.client.command.Command;
import org.soupframework.gwt.designerpanel.client.command.CommandFactory;
import org.soupframework.gwt.designerpanel.client.command.CommandGroup;
import org.soupframework.gwt.designerpanel.client.decorator.ObjectDecorator;
import org.soupframework.gwt.designerpanel.client.dragproxy.DragProxyFactory;
import org.soupframework.gwt.designerpanel.client.grid.GridMode;

/**
 *
 * @param <T> represents the type of the objects being designed
 */
public interface DesignerManager<T> {

	/**
	 * Gets the {@link DesignerPanel}
	 * @return
	 */
	public DesignerPanel<T> getDesignerPanel();

	/**
	 * Gets the root {@link Designer}
	 *
	 * @return the root {@link Designer}
	 */
	public Designer<T> getRootDesigner();

	/**
	 * Sets the {@link CommandFactory} for this manager
	 *
	 * @param commandFactory the {@link CommandFactory}
	 */
	public void setCommandFactory(CommandFactory<T> commandFactory);

	/**
	 * Returns the {@link CommandFactory} for this manager
	 *
	 * @return the {@link CommandFactory}
	 */
	public CommandFactory<T> getCommandFactory();

	/**
	 * Sets the {@link ContextMenuFactory} for this manager
	 *
	 * @param contextMenuFactory the {@link ContextMenuFactory}
	 */
	public void setContextMenuFactory(ContextMenuFactory<T> contextMenuFactory);

	/**
	 * Returns the {@link ContextMenuFactory} for this manager
	 *
	 * @return the {@link ContextMenuFactory}
	 */
	public ContextMenuFactory<T> getContextMenuFactory();

	/**
	 * Gets the operating mode for designers
	 *
	 * @return the operating mode
	 */
	public OperatingMode getOperatingMode();

	/**
	 * Sets the operating mode for designers
	 * @param operatingMode the operating mode
	 */
	public void setOperatingMode(OperatingMode operatingMode);

	/**
	 * Refresh {@link Designer}s managed by this manager.
	 */
	public void refreshDesigners();

	/**
	 * Shows the grid
	 */
	public void showGrid();

	/**
	 * Hides the grid
	 */
	public void hideGrid();

	/**
	 * Gets the grid mode.
	 *
	 * @return The grid mode
	 */
	public GridMode getGridMode();

	/**
	 * Sets the grid mode
	 */
	public void setGridMode(GridMode gridMode);

	/**
	 * Enable command history
	 */
	public void enableHistory();

	/**
	 * Disable command history
	 */
	public void disableHistory();

	/**
	 * Gets the size of the command history
	 */
	public int getHistorySize();

	/**
	 * Gets the last {@link Command} that has executed
	 *
	 * @return The last executed {@link Command}
	 */
	public Command peekLastCommandDone();

	/**
	 * Executes a command and store it in history, if history is enabled
	 *
	 * @param command the {@link Command} to execute
	 */
	public void doCommand(Command command);

	/**
	 * Undo the last command done if history is enabled
	 */
	public void undo();

	/**
	 * Redo the last command un-done if history is enabled
	 */
	public void redo();

	/**
	 * Executes a command and cumulate it in the with previous commands in history if they were of the same type.
	 * Otherwise it creates a new {@link CommandGroup} and push it in history.
	 * If history is not enabled the {@link Command} is executed and nothing more is done.
	 *
	 * @param commandGroupType the type of the {@link CommandGroup} to check for in history 
	 * @param command the {@link Command} to execute
	 */
	public void doPartialCommand(String commandGroupType, Command command);

	/**
	 * Puts a new command group on the history top.
	 * Subsequent commands are put inside this command group until a endCommandGroup call is performed.
	 * If history is not active this command has no effects.
	 *
	 * @param commandGroupTypeName The name of the command group type
	 */
	public void beginCommandGroup(String commandGroupTypeName);

	/**
	 * Close a previously started command group. If history is not active this command has no effects.
	 *
	 * @param commandGroupTypeName The name of the command group type
	 */
	public void endCommandGroup(String commandGroupTypeName);

	/**
	 * Gets the highlighter {@link ObjectDecorator}
	 *
	 * @return the highlighter {@link ObjectDecorator}
	 */
	public ObjectDecorator<T> getObjectHighlighter();

	/**
	 * Sets the {@link ObjectDecorator}
	 *
	 * @param objectHighligher the {@link ObjectDecorator}
	 */
	public void setObjectHighlighter(ObjectDecorator<T> objectHighlighter);

	/**
	 * Gets the Design Mode {@link ObjectDecorator} for containers
	 *
	 * @return the {@link ObjectDecorator} for containers
	 */
	public ObjectDecorator<T> getContainerDesignModeDecorator();

	/**
	 * Sets the Design Mode {@link ObjectDecorator} for containers
	 *
	 * @param containerDesignHighlighter the {@link ObjectDecorator} for containers
	 */
	public void setContainerDesignModeDecorator(ObjectDecorator<T> containerDesignHighlighter);

	/**
	 * Gets the {@link DragProxyFactory}
	 *
	 * @return The {@link DragProxyFactory}
	 */
	public DragProxyFactory<T> getDragProxyFactory();

	/**
	 * Sets the {@link DragProxyFactory}
	 *
	 * @param dragProxyFactory The {@link DragProxyFactory}
	 */
	public void setDragProxyFactory(DragProxyFactory<T> dragProxyFactory);

	/**
	 * Gets the resize points {@link ObjectDecorator}
	 *
	 * @return the resize points {@link ObjectDecorator}
	 */
	public ObjectDecorator<T> getResizePointsDecorator();

	/**
	 * Sets the resize points {@link ObjectDecorator}
	 *
	 * @param resizePointsDecorator the resize points {@link ObjectDecorator}
	 */
	public void setResizePointsDecorator(ObjectDecorator<T> resizePointsDecorator);
}
